using System.Xml;
using UnityEngine;
using System;

[Serializable]
public class BaseProperty
{
    protected float _healthPoint;
    protected float _moveSpeed;
    protected float _turningSpeed;
    protected float _armor;
    public virtual float HealthPoint { get => _healthPoint; set => _healthPoint = value; }
    public virtual float MoveSpeed { get => _moveSpeed; set => _moveSpeed = value; }
    public virtual float TurningSpeed { get => _turningSpeed; set => _turningSpeed = value; }
    public virtual float Armor { get => _armor; set => _armor = value; }
    public BaseProperty(BaseProperty baseProperty)
    {
        HealthPoint = baseProperty.HealthPoint;
        MoveSpeed = baseProperty.MoveSpeed;
        TurningSpeed = baseProperty.TurningSpeed;
        Armor = baseProperty.Armor;
    }
    public BaseProperty(float data)
    {
        HealthPoint = data;
        MoveSpeed = data;
        TurningSpeed = data;
        Armor = data;
    }
    public BaseProperty(string[] data)
    {
        if (data.Length == 1)
        {
            HealthPoint = float.Parse(data[0]);
            MoveSpeed = float.Parse(data[0]);
            TurningSpeed = float.Parse(data[0]);
            Armor = float.Parse(data[0]);
        }
        else
        {
            HealthPoint = float.Parse(data[0]);
            MoveSpeed = float.Parse(data[1]);
            TurningSpeed = float.Parse(data[2]);
            Armor = float.Parse(data[3]);
        }
    }
    public BaseProperty(float data0, float data1, float data2, float data3)
    {
        HealthPoint = data0;
        MoveSpeed = data1;
        TurningSpeed = data2;
        Armor = data3;
    }
    public static BaseProperty operator +(BaseProperty property1, BaseProperty property2)
    {
        return new BaseProperty(
            property1.HealthPoint + property2.HealthPoint,
            property1.MoveSpeed + property2.MoveSpeed,
            property1.TurningSpeed + property2.TurningSpeed,
            property1.Armor + property2.Armor);
    }
    public static BaseProperty operator *(BaseProperty property1, BaseProperty property2)
    {
        return new BaseProperty(
            property1.HealthPoint * property2.HealthPoint,
            property1.MoveSpeed * property2.MoveSpeed,
            property1.TurningSpeed * property2.TurningSpeed,
            property1.Armor * property2.Armor);
    }
}

public class MainFrameProperty : BaseProperty
{
    public override float HealthPoint { get => _healthPoint; set => _healthPoint = Mathf.Max(0, value); }
    public override float MoveSpeed { get => _moveSpeed; set => _moveSpeed = Mathf.Max(0, value); }
    public override float TurningSpeed { get => _turningSpeed; set => _turningSpeed = Mathf.Max(0, value); }
    public override float Armor { get => _armor; set => _armor = value; }
    public MainFrameProperty(BaseProperty baseProperty) : base(baseProperty) { }
    public MainFrameProperty(float data0, float data1, float data2, float data3) : base(data0, data1, data2, data3) { }
}

[Serializable]
public class WeaponProperty
{
    private float _fireRate;
    private float _turningSpeed;
    public float FireRate { get => _fireRate; set => _fireRate = Mathf.Max(0, value); }
    public float TurningSpeed { get => _turningSpeed; set => _turningSpeed = Mathf.Max(0, value); }

    public WeaponProperty(float data)
    {
        FireRate = data;
        TurningSpeed = data;
    }
    public WeaponProperty(string[] data)
    {
        if (data.Length == 1)
        {
            FireRate = float.Parse(data[0]);
            TurningSpeed = float.Parse(data[0]);
        }
        else
        {
            FireRate = float.Parse(data[0]);
            TurningSpeed = float.Parse(data[1]);
        }
    }
    public WeaponProperty(float data0, float data1)
    {
        FireRate = data0;
        TurningSpeed = data1;
    }
    public static WeaponProperty operator +(WeaponProperty property1, WeaponProperty property2)
    {
        return new WeaponProperty(
            property1.FireRate + property2.FireRate,
            property1.TurningSpeed + property2.TurningSpeed);
    }
    public static WeaponProperty operator *(WeaponProperty property1, WeaponProperty property2)
    {
        return new WeaponProperty(
            property1.FireRate * property2.FireRate,
            property1.TurningSpeed * property2.TurningSpeed);
    }
}

[Serializable]
public class PropertyModifier
{
    public BaseProperty _baseAdd;
    public BaseProperty _basePercentage;
    public BaseProperty _baseAddition;
    public WeaponProperty _weaponAdd;
    public WeaponProperty _weaponPercentage;
    public WeaponProperty _weaponAddition;
    public bool _isActive;

    public PropertyModifier()
    {
        _baseAdd = new BaseProperty(0);
        _basePercentage = new BaseProperty(1);
        _baseAddition = new BaseProperty(0);
        _weaponAdd = new WeaponProperty(0);
        _weaponPercentage = new WeaponProperty(1);
        _weaponAddition = new WeaponProperty(0);
        _isActive = true;
    }
    public PropertyModifier(BaseProperty baseAdd, BaseProperty basePer, BaseProperty baseAddi, WeaponProperty weaponAdd, WeaponProperty weaponPer, WeaponProperty weaponAddi)
    {
        _baseAdd = baseAdd;
        _basePercentage = basePer;
        _baseAddition = baseAddi;
        _weaponAdd = weaponAdd;
        _weaponPercentage = weaponPer;
        _weaponAddition = weaponAddi;
        _isActive = true;
    }
    public PropertyModifier(XmlAttributeCollection xmlAttributes)
    {
        _baseAdd = new BaseProperty(xmlAttributes[0].Value.Split(','));
        _basePercentage = new BaseProperty(xmlAttributes[1].Value.Split(','));
        _baseAddition = new BaseProperty(xmlAttributes[2].Value.Split(','));
        _weaponAdd = new WeaponProperty(xmlAttributes[3].Value.Split(','));
        _weaponPercentage = new WeaponProperty(xmlAttributes[4].Value.Split(','));
        _weaponAddition = new WeaponProperty(xmlAttributes[5].Value.Split(','));
        _isActive = true;
    }
    public static PropertyModifier operator +(PropertyModifier propertyModifier1, PropertyModifier propertyModifier2)
    {
        return new PropertyModifier(
            propertyModifier1._baseAdd + propertyModifier2._baseAdd,
            propertyModifier1._basePercentage + propertyModifier2._basePercentage,
            propertyModifier1._baseAddition + propertyModifier2._baseAddition,
            propertyModifier1._weaponAdd + propertyModifier2._weaponAdd,
            propertyModifier1._weaponPercentage + propertyModifier2._weaponPercentage,
            propertyModifier1._weaponAddition + propertyModifier2._weaponAddition);
    }
    public static PropertyModifier operator *(PropertyModifier propertyModifier1, PropertyModifier propertyModifier2)
    {
        return new PropertyModifier(
            propertyModifier1._baseAdd * propertyModifier2._baseAdd,
            propertyModifier1._basePercentage * propertyModifier2._basePercentage,
            propertyModifier1._baseAddition * propertyModifier2._baseAddition,
            propertyModifier1._weaponAdd * propertyModifier2._weaponAdd,
            propertyModifier1._weaponPercentage * propertyModifier2._weaponPercentage,
            propertyModifier1._weaponAddition * propertyModifier2._weaponAddition);
    }

    public void IReact(bool condition)//todo
    {
        _isActive = condition;
    }
}
